Skip to content

[None][test] Declare supported attention test phases#16718

Merged
yihwang-nv merged 2 commits into
NVIDIA:mainfrom
yihwang-nv:vanilla-mla-phases
Jul 24, 2026
Merged

[None][test] Declare supported attention test phases#16718
yihwang-nv merged 2 commits into
NVIDIA:mainfrom
yihwang-nv:vanilla-mla-phases

Conversation

@yihwang-nv

@yihwang-nv yihwang-nv commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Replace mla_context inference with an explicit immutable phases declaration limited to ctx and gen.
  • Keep the existing ctx, gen, and mix cases for standard attention when phases=None.
  • Let dense MLA configs select their single supported path explicitly. A future DSA config can declare both ctx and gen without implying an MLA mixed batch.
  • Retain the existing standard-attention split-consistency coverage.

Testing

  • Pre-commit: ruff, ruff-format, codespell, commit-message DCO, and other applicable hooks passed.
  • B200 Docker: representative dense-MLA ctx/gen KVCacheManagerV2 cases: 6 passed before the review-only restoration of unchanged standard-attention coverage.
  • A fresh Docker rerun is pending because the previous GPU allocations expired; CI is requested for the updated commit.

Dev Engineer Review

  • Updates MLA attention test configurations to replace the boolean mla_context with an explicit, immutable phases: tuple[AttentionPhase, ...] | None where AttentionPhase = Literal["ctx", "gen"].
  • MLA config entries now encode absorbed-generation vs context-pass behavior via phases=("gen",) (for _mla variants) and phases=("ctx",) (for *_mla_ctx variants).
  • Refactors backend test phase emission logic: introduces _phases_to_run(cfg, available_phases) and uses it to generate backend cases based on cfg.phases (defaulting to all available phases when unspecified).
  • Updates cross-phase wording in the test module docs from {ctx, dec, mix} to {ctx, gen, mix}.
  • No changes detected to test-list files; test coverage mappings remain consistent with the modified unit test module.

QA Engineer Review

  • Test code changes (under tests/): modified
    • tests/unittest/_torch/attention/model_attn_config.py
    • tests/unittest/_torch/attention/test_attention_backends.py
  • Test functions added/removed:
    • No test functions added/removed in test_attention_backends.py (the existing test_attention_backend and test_split_consistency remain); changes are to helper logic and parametrization generation.
  • Coverage in tests/integration/test_lists/:
    • tests/integration/test_lists/test-db/l0_*.yml includes unittest/_torch/attention (covers this module).
    • tests/integration/test_lists/waives.txt contains SKIPs for specific test_attention_backend[...] parametrizations in this module.
  • Verdict: sufficient (CI/test-list coverage already includes this unit test module; behavior changes are exercised via the existing parametrized sweep).

@yihwang-nv
yihwang-nv requested review from a team as code owners July 22, 2026 09:06
@yihwang-nv yihwang-nv changed the title [None][feat] Add paged KV cache support to Vanilla attention [None][test] Attention sweep: declare MLA phases instead of mla_context Jul 22, 2026
@yihwang-nv
yihwang-nv requested a review from yuxianq July 22, 2026 09:09
@yihwang-nv
yihwang-nv force-pushed the vanilla-mla-phases branch from 760ef7e to 9543131 Compare July 22, 2026 09:12
@yihwang-nv yihwang-nv changed the title [None][test] Attention sweep: declare MLA phases instead of mla_context [None][test] Declare supported attention test phases Jul 22, 2026
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Attention model configurations now declare optional context or generation phases. Backend attention test expansion selects configured phases or all available phases by default, replacing MLA-specific context branching with phase-based selection.

Changes

Attention phase selection

Layer / File(s) Summary
Phase configuration contract
tests/unittest/_torch/attention/model_attn_config.py
ModelAttnConfig replaces mla_context with typed optional phases, and MLA variants declare either ctx or gen.
Phase-aware backend case expansion
tests/unittest/_torch/attention/test_attention_backends.py
Backend cases use configured phase names or all available phases by default; cross cases continue to use ctx entries.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: kris1025

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and directly reflects the main change: declaring supported attention test phases.
Description check ✅ Passed The description covers the summary and testing clearly, with only the PR Checklist section omitted.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
tests/unittest/_torch/attention/test_attention_backends.py (1)

230-232: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate the new test function.

Add precise parameter and -> None annotations, consistent with the Python typing guideline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/attention/test_attention_backends.py` around lines 230
- 232, Update test_phases_to_run with precise type annotations for the declared
and expected parameters, and add a -> None return annotation. Use the existing
typing conventions and types implied by ModelAttnConfig phases and
_phases_to_run.

Source: Coding guidelines

tests/unittest/_torch/attention/model_attn_config.py (1)

77-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use PEP 604 syntax for the new optional field.

-    phases: Optional[tuple[AttentionPhase, ...]] = None
+    phases: tuple[AttentionPhase, ...] | None = None

As per coding guidelines, prefer built-in generic types and |.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/attention/model_attn_config.py` at line 77, Update the
phases field annotation to use PEP 604 union syntax with the built-in tuple
generic, replacing Optional while preserving the existing AttentionPhase tuple
and None default.

Source: Coding guidelines

tensorrt_llm/_torch/attention_backend/vanilla.py (2)

589-591: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

cache_indices = [list(block_ids) for block_ids in metadata.block_ids_per_seq] is duplicated verbatim between _mla_forward_generation and forward.

Both the MLA-generation path (lines 589-591) and the standard forward() path (lines 731-733) materialize per-request block-id lists identically. Extracting this into a small metadata/helper accessor would reduce the risk of the two call sites diverging as the paged-cache logic evolves further.

Also applies to: 731-733

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/_torch/attention_backend/vanilla.py` around lines 589 - 591,
Extract the duplicated block-ID materialization into a shared metadata helper or
accessor, then update both `_mla_forward_generation` and `forward` to use it
instead of constructing `cache_indices` inline. Preserve the existing
per-request list output and avoid changing the paged-cache behavior.

204-219: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Write path silently trusts that new-token block_ids are never BAD_PAGE_INDEX.

Unlike the read path (_gather_paged_kv/_gather_paged_mla_latent), which explicitly checks blk == BAD_PAGE_INDEX, this write loop does kv_cache_tensor[blk, 0] unconditionally. Since BAD_PAGE_INDEX == -1, if this invariant is ever violated (e.g. a KV-manager bug hands back an evicted/unallocated block for a new-token position), PyTorch's negative indexing silently wraps to the last page instead of raising, corrupting an unrelated request's cache with no error signal. An assertion here would convert a silent-corruption bug into a loud, debuggable failure.

🛡️ Proposed defensive assertion
             while written < kv_len:
                 pos = past_seen_token + written
                 blk = block_ids[pos // tokens_per_block]
+                assert blk != BAD_PAGE_INDEX, (
+                    "New KV token position mapped to an invalid page; "
+                    "cache manager must allocate blocks before writing new tokens.")
                 off = pos % tokens_per_block
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/_torch/attention_backend/vanilla.py` around lines 204 - 219, Add
a defensive assertion in the k/v cache write loop before indexing
kv_cache_tensor, validating that blk is not BAD_PAGE_INDEX. Keep the existing
block and offset calculations unchanged, and ensure an invalid new-token block
fails loudly instead of allowing negative indexing to write to the final page.
tests/unittest/_torch/executor/test_py_executor_creator_flash_mla_tokens_per_block.py (1)

94-102: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Regex regression guard is narrower than its sibling and may miss reintroductions of the bug it guards against.

test_flash_mla_tokens_per_block_propagates_to_kv_cache_config (lines 61-91, unchanged) captures the entire branch body via ((?:[ \t]+.*\n)+) and then searches within it. This new test instead requires the offending assignment to appear as the immediate next line after the if (\s*tokens_per_block\s*=\s*max_num_tokens right after the \n). If the anti-pattern were reintroduced with an intervening comment/blank line, inside an elif, or a few lines further into the branch body, this regex would not match and the test would pass while VANILLA is still (incorrectly) linearized.

Consider mirroring the sibling test's approach: capture the full branch body first, then assert the offending pattern is absent from it.

♻️ Suggested widening
 def test_vanilla_preserves_configured_tokens_per_block():
     """Vanilla supports paged KV and must honor the configured page size."""
     source = _get_create_py_executor_source()
 
-    assert not re.search(
-        r"if\s+llm_args\.attn_backend\s*==\s*[\"']VANILLA[\"']\s*:\s*\n"
-        r"\s*tokens_per_block\s*=\s*max_num_tokens",
-        source,
-    ), "Vanilla must not linearize the KV cache by overriding tokens_per_block."
+    vanilla_block_match = re.search(
+        r"if\s+llm_args\.attn_backend\s*==\s*[\"']VANILLA[\"']\s*:\s*\n"
+        r"((?:[ \t]+.*\n)+)",
+        source,
+    )
+    if vanilla_block_match:
+        assert "tokens_per_block = max_num_tokens" not in vanilla_block_match.group(1), (
+            "Vanilla must not linearize the KV cache by overriding tokens_per_block.")

Test coverage summary (QA). Added test function: test_vanilla_preserves_configured_tokens_per_block — new, source-inspection regression guard ensuring VANILLA doesn't linearize the KV cache via tokens_per_block = max_num_tokens. No existing tests modified/removed. Coverage verdict: needs follow-up — registration in tests/integration/test_lists/test-db/ or qa/ could not be confirmed from provided context.
As per path instructions for tests/**: "Always produce a test coverage summary, even if no issues are found."

#!/bin/bash
rg -n "test_py_executor_creator_flash_mla_tokens_per_block" tests/integration/test_lists --glob '*.txt' --glob '*.yml' -C2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@tests/unittest/_torch/executor/test_py_executor_creator_flash_mla_tokens_per_block.py`
around lines 94 - 102, The regex in
test_vanilla_preserves_configured_tokens_per_block is too narrow and only
detects an immediate assignment after the VANILLA condition. Mirror
test_flash_mla_tokens_per_block_propagates_to_kv_cache_config by capturing the
entire VANILLA branch body, then assert that body does not contain
tokens_per_block = max_num_tokens, including when separated by comments, blank
lines, or branch statements.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tensorrt_llm/_torch/attention_backend/vanilla.py`:
- Around line 164-183: Update _gather_paged_mla_latent to return an
appropriately shaped empty tensor when kv_len is less than or equal to zero,
matching the existing guard behavior in _gather_paged_kv; keep the current paged
gathering logic unchanged for positive lengths.

---

Nitpick comments:
In `@tensorrt_llm/_torch/attention_backend/vanilla.py`:
- Around line 589-591: Extract the duplicated block-ID materialization into a
shared metadata helper or accessor, then update both `_mla_forward_generation`
and `forward` to use it instead of constructing `cache_indices` inline. Preserve
the existing per-request list output and avoid changing the paged-cache
behavior.
- Around line 204-219: Add a defensive assertion in the k/v cache write loop
before indexing kv_cache_tensor, validating that blk is not BAD_PAGE_INDEX. Keep
the existing block and offset calculations unchanged, and ensure an invalid
new-token block fails loudly instead of allowing negative indexing to write to
the final page.

In `@tests/unittest/_torch/attention/model_attn_config.py`:
- Line 77: Update the phases field annotation to use PEP 604 union syntax with
the built-in tuple generic, replacing Optional while preserving the existing
AttentionPhase tuple and None default.

In `@tests/unittest/_torch/attention/test_attention_backends.py`:
- Around line 230-232: Update test_phases_to_run with precise type annotations
for the declared and expected parameters, and add a -> None return annotation.
Use the existing typing conventions and types implied by ModelAttnConfig phases
and _phases_to_run.

In
`@tests/unittest/_torch/executor/test_py_executor_creator_flash_mla_tokens_per_block.py`:
- Around line 94-102: The regex in
test_vanilla_preserves_configured_tokens_per_block is too narrow and only
detects an immediate assignment after the VANILLA condition. Mirror
test_flash_mla_tokens_per_block_propagates_to_kv_cache_config by capturing the
entire VANILLA branch body, then assert that body does not contain
tokens_per_block = max_num_tokens, including when separated by comments, blank
lines, or branch statements.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5f9e76bb-bd51-4463-98ea-109b8a9b9883

📥 Commits

Reviewing files that changed from the base of the PR and between 9095cc1 and 760ef7e.

📒 Files selected for processing (7)
  • tensorrt_llm/_torch/attention_backend/vanilla.py
  • tensorrt_llm/_torch/pyexecutor/py_executor_creator.py
  • tests/unittest/_torch/attention/backend_capability.py
  • tests/unittest/_torch/attention/model_attn_config.py
  • tests/unittest/_torch/attention/test_attention_backends.py
  • tests/unittest/_torch/attention/test_vanilla_attention.py
  • tests/unittest/_torch/executor/test_py_executor_creator_flash_mla_tokens_per_block.py
💤 Files with no reviewable changes (1)
  • tensorrt_llm/_torch/pyexecutor/py_executor_creator.py

Comment thread tensorrt_llm/_torch/attention_backend/vanilla.py Outdated
@yihwang-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #60952 [ run ] triggered by Bot. Commit: 9543131 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #60952 [ run ] completed with state FAILURE. Commit: 9543131
/LLM/main/L0_MergeRequest_PR pipeline #49215 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

Comment thread tests/unittest/_torch/attention/test_attention_backends.py
Comment thread tests/unittest/_torch/attention/test_attention_backends.py Outdated
Comment thread tests/unittest/_torch/attention/test_attention_backends.py
Replace mla_context with phases so each model attention config declares whether it supports context, generation, or both.

Keep the existing context, generation, and mixed cases for standard attention when phases is None. Explicit MLA phases select only their declared atomic paths, so a config supporting context and generation does not imply an MLA mixed batch.

Use immutable typed tuples for phase declarations.

Signed-off-by: Yihan Wang <yihwang@nvidia.com>
@yihwang-nv
yihwang-nv force-pushed the vanilla-mla-phases branch from 9543131 to f1abeba Compare July 23, 2026 05:29
@yihwang-nv

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61200 [ run ] triggered by Bot. Commit: f1abeba Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61200 [ run ] completed with state FAILURE. Commit: f1abeba
/LLM/main/L0_MergeRequest_PR pipeline #49445 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yihwang-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61258 [ run ] triggered by Bot. Commit: f1abeba Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61258 [ run ] completed with state FAILURE. Commit: f1abeba
/LLM/main/L0_MergeRequest_PR pipeline #49493 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yihwang-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61487 [ run ] triggered by Bot. Commit: 2570af5 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #61487 [ run ] completed with state SUCCESS. Commit: 2570af5
/LLM/main/L0_MergeRequest_PR pipeline #49708 completed with status: 'SUCCESS'

CI Report

Link to invocation

@yihwang-nv
yihwang-nv merged commit 8a6cb44 into NVIDIA:main Jul 24, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants